﻿using HlELock.Core;
using HlELock.Core.Events;
using HlELock.Core.ViewModels;
using HlELock.Core.Views;
using HlELock.Domain;
using HlELock.Domain.Entities;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Prism.Commands;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Documents;
using System.Windows.Forms;

namespace HlELock.Modules.Hotel.Main.ViewModels
{
    internal class CheckInPageViewModel : CheckIn
    {
        private readonly IDialogService _dialogService;
        public CheckInPageViewModel(IDialogService dialogService)
        {
            BeginTime = DateTime.Now;
            Days = 1;
            using (var context = new HlELockDbContext())
            {
                Rooms = context
                    .Rooms
                    .OrderBy(o => o.RoomNumber)
                    .Where(w => !w.IsOccupancies)
                    .ToList();

                var rooms = Rooms
                    .Where(w => !w.IsOccupancies)
                    .GroupBy(o => o.RoomType)
                    .Select(s => new CheckInRoomInfo
                    {
                        Name = s.Key,
                        Qty = s.Count()
                    }).ToObservableCollection();

                var roomTypes = context.RoomTypes.ToList();

                foreach (var room in rooms)
                {
                    var type = roomTypes.FirstOrDefault(f => f.Name == room.Name);
                    if (type != null)
                    {
                        room.Price = type.Price;
                    }
                    room.Rooms = Rooms.Where(w => w.RoomType == type.Name).ToObservableCollection();
                    room.CheckInQtyChanged += Room_CheckInQtyChanged;
                }
                CheckInRoomInfos = rooms;
                //foreach (var item in CheckInRoomInfos)
                //{
                //    item.CheckInQty = 1;
                //}
            }
            _dialogService = dialogService;

            Gender = AppHelper.GetResourceString("NanShi");
            IdType = AppHelper.GetStrings("ZhengJianLeiXingList").FirstOrDefault();
        }

        private bool _isCheckIn;
        /// <summary>
        /// 是否已入住
        /// </summary>
        public bool IsCheckIn
        {
            get { return _isCheckIn; }
            set
            {
                SetProperty(ref _isCheckIn, value);
                SendCardCommand.RaiseCanExecuteChanged();
                CheckInCommand.RaiseCanExecuteChanged();
            }
        }

        private DelegateCommand _sendCardCommand;
        public DelegateCommand SendCardCommand =>
            _sendCardCommand ?? (_sendCardCommand = new DelegateCommand(ExecuteSendCardCommand, () => IsCheckIn));

        private DelegateCommand _returnRoomCommand;
        public DelegateCommand ReturnRoomCommand =>
            _returnRoomCommand ?? (_returnRoomCommand = new DelegateCommand(ExecuteReturnRoomCommand));


        /// <summary>
        /// 退房
        /// </summary>
        void ExecuteReturnRoomCommand()
        {

        }

        /// <summary>
        /// 发卡
        /// </summary>
        void ExecuteSendCardCommand()
        {

        }

        private DelegateCommand _checkInCommand;
        public DelegateCommand CheckInCommand =>
            _checkInCommand ?? (_checkInCommand = new DelegateCommand(ExecuteCheckInCommand, () => !IsCheckIn));

        /// <summary>
        /// 输入住
        /// </summary>
        void ExecuteCheckInCommand()
        {
            if (!Name.Required(AppHelper.GetResourceString("XingMing")))
            {
                return;
            }

            if (!Gender.Required(AppHelper.GetResourceString("XingBie")))
            {
                return;
            }

            if (!IdType.Required(AppHelper.GetResourceString("ZhengJianLeiXing")))
            {
                return;
            }

            if (!IdNumber.Required(AppHelper.GetResourceString("ZhengJianHao")))
            {
                return;
            }

            if (!Days.Required(AppHelper.GetResourceString("RuZhuTianShu")))
            {
                return;
            }
            var rNumbers = CheckInRoomInfos.SelectMany(s => s.RoomNumbers).ToArray();
            if (!string.Join("", rNumbers).Required(AppHelper.GetResourceString("RuZhuFangHao")))
            {
                return;
            }


            using (var dbConext = new HlELockDbContext())
            {
                this.CheckInRooms = new List<CheckInRoom>();

                foreach (var item in CheckInRoomInfos)
                {
                    foreach (var room in item.RoomNumbers)
                    {
                        var checkInRoom = new CheckInRoom
                        {
                            CheckInTime = BeginTime,
                            CheckOutTime = null,
                            Price = item.Price,
                            RoomNumber = room,
                            RoomType = item.Name,
                            Feature = item.Feature,
                            CreationTime = DateTime.Now
                        };
                        CheckInRooms.Add(checkInRoom);
                    }
                }
                dbConext.Add(this);
                dbConext.SaveChanges();
                IsCheckIn = true;
            }
            EventBus.CloseDialog();
        }

        private List<Room> Rooms { get; set; }


        private DelegateCommand<string> _roomNumberCommand;
        public DelegateCommand<string> RoomNumberCommand =>
            _roomNumberCommand ?? (_roomNumberCommand = new DelegateCommand<string>(ExecuteRoomNumberCommand));

        /// <summary>
        /// 修改房号命令
        /// </summary>
        void ExecuteRoomNumberCommand(string number)
        {
            var args = new DialogParameters();
            var currentRoom = Rooms.First(w => w.RoomNumber == number);

            var rooms = Rooms.Where(w => w.RoomType == currentRoom.RoomType && CheckInRoomInfos.SelectMany(s => s.RoomNumbers).All(a => a != w.RoomNumber)).ToList();

            args.Add("args", rooms);
            _dialogService.ShowDialog(nameof(SelectRoomUserControl), args, arg =>
            {
                if (arg.Result == ButtonResult.OK)
                {
                    var room = arg.Parameters.GetValue<Room>("args");
                    if (room != null)
                    {
                        foreach (var item in CheckInRoomInfos)
                        {
                            if (item.RoomNumbers.Contains(number))
                            {
                                item.RoomNumbers.Remove(number);
                                item.RoomNumbers.Add(room.RoomNumber);
                            }

                        }
                    }
                }
                else
                {

                }

            }, nameof(PrismDialogWindow));
        }



        private void Room_CheckInQtyChanged(CheckInRoomInfo checkInRoomInfo)
        {
            checkInRoomInfo.RoomNumbers = Rooms
                .Where(w => w.RoomType == checkInRoomInfo.Name)
                .Take(checkInRoomInfo.CheckInQty).Select(s => s.RoomNumber).ToObservableCollection();
            Amount = CheckInRoomInfos.Where(w => w.CheckInQty > 0).Sum(s => s.CheckInQty * s.Price);
            TotalQty = CheckInRoomInfos.Where(w => w.CheckInQty > 0).Sum(s => s.CheckInQty);
        }

        private decimal _amount;
        /// <summary>
        /// 总金额
        /// </summary>
        public decimal Amount
        {
            get { return _amount; }
            set { SetProperty(ref _amount, value); }
        }

        private int _totalQty;
        /// <summary>
        /// 总间数
        /// </summary>
        public int TotalQty
        {
            get { return _totalQty; }
            set { SetProperty(ref _totalQty, value); }
        }
        public ObservableCollection<CheckInRoomInfo> CheckInRoomInfos { get; set; }

    }

    public class CheckInRoomInfo : BindableBase
    {
        public CheckInRoomInfo()
        {
            RoomNumbers = new ObservableCollection<string>();
        }
        public event Action<CheckInRoomInfo> CheckInQtyChanged;
        public string Name { get; set; }
        public int Qty { get; set; }
        public decimal Price { get; set; }

        public string Feature { get; set; }

        private int _checkInQty;
        public int CheckInQty
        {
            get => _checkInQty; set
            {
                SetProperty(ref _checkInQty, value);
                CheckInQtyChanged?.Invoke(this);
            }
        }
        private ObservableCollection<Room> _rooms;
        public ObservableCollection<Room> Rooms
        {
            get { return _rooms; }
            set { SetProperty(ref _rooms, value); }
        }
        private ObservableCollection<string> _roomNumbers;
        public ObservableCollection<string> RoomNumbers
        {
            get { return _roomNumbers; }
            set { SetProperty(ref _roomNumbers, value); }
        }
    }
}
